using System;
using System.Diagnostics;
using System.Reflection;

public class Debug
{
	public static bool DebugEnabled = true;
	public static bool WarningEnabled = true;
	public static bool ErrorEnabled = true;

	private const int MAX_MESSAGE_LEN = 1000;

	private static string TrimMessage(string message)
	{
		int l = message.Length;
		if (l > MAX_MESSAGE_LEN)
		{
			return message.Substring(0, MAX_MESSAGE_LEN)+" [... "+(l-MAX_MESSAGE_LEN)+" chars]";
		}
		return message;
	}

	public static void LogFormat(string message, params object[] args)
	{
		LogFormat(false, message, args);
	}

	// only do formatting if logging is enabled
	public static void LogFormat(bool always, string message, params object[] args)
	{
		if (DebugEnabled || always)
		{
			Console.WriteLine(TrimMessage(string.Format(message, args)));
		}
	}

	public static void LogWarningFormat(string message, params object[] args)
	{
		if (WarningEnabled)
		{
            Console.WriteLine("WARNING " + TrimMessage(string.Format(message, args)));
		}
	}

	public static void LogErrorFormat(string message, params object[] args)
	{
		if (ErrorEnabled)
		{
            Console.WriteLine("ERROR " + TrimMessage(string.Format(message, args)));
		}
	}

	public static string GetStack ()
	{
		StackTrace trace = new StackTrace();
		string log = "";

		foreach (StackFrame frame in trace.GetFrames())
		{
			MethodBase method = frame.GetMethod();

			if (method.Name.Equals("LogStack")) 
				continue;

			log += string.Format("{0}::{1}()" + System.Environment.NewLine, (method.ReflectedType != null ? method.ReflectedType.Name : string.Empty), method.Name);
		}

		return log;
	}

    public static void Log(object message)
	{
		if (DebugEnabled)
		{
            Console.WriteLine(message);
		}
	}

	public static void LogWarning(object message)
	{
		if (WarningEnabled)
		{
            Console.WriteLine("WARNING " + message);
		}
	}

	public static void LogError(object message)
	{
		if (ErrorEnabled)
		{
            Console.WriteLine("ERROR " + message);
		}
	}

	public static void LogException(Exception exception)
	{
		if (ErrorEnabled)
		{
            Console.WriteLine("ERROR " + exception.Message);
		}
	}

	public static void Assert(bool condition)
	{
		System.Diagnostics.Debug.Assert(condition);
	}
}

